package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.context.FlowElementProcessContext;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.EventCallTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.NodeOperEventTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.CustomPropertiesProcessor;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.eventconfig.DeployedEventConfigDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowEventConfigRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Optional;

/**
 * @author: liyang
 * @date: 2021/11/9 17:06
 */
@Component
public class SaveNodeOperationEventProcessor implements CustomPropertiesProcessor {

    private String NODE_OPER_EVENTS = "nodeOperEvents";

    //before , after
    private String OPER_EVENT_TYPE = "operEventType";

    //退回到上一节点或者退回到第一个节点
    private String NODE_OPER_TYPE = "nodeOperType";

    //请求地址
    private String CALL_URL = "callUrl";

    //异步、同步
    private String CALL_TYPE = "callType";

    //请求体
    private String REQUEST_BODY = "requestBody";

    @Autowired
    private FlowEventConfigRepository eventConfigRepository;

    @Override
    public boolean support(JsonNode elementNode) {
        JsonNode properties = elementNode.get("properties");
        if (nonNull(properties)) {
            return nonNull(properties.get(NODE_OPER_EVENTS));
        }
        return false;
    }

    @Override
    public void process(FlowElementProcessContext context) {
        JsonNode jsonNode = context.getElementNode();
        JsonNode properties = jsonNode.get("properties");
        JsonNode nodeOperationEventList = properties.get(NODE_OPER_EVENTS);
        if (Objects.nonNull(nodeOperationEventList)
                && nodeOperationEventList instanceof ArrayNode){
            String nodeCode = context.getActivity().getId();

            ArrayNode arrayNode = (ArrayNode) nodeOperationEventList;

            for (JsonNode node : arrayNode) {
                JsonNode nodeOperType = node.get(NODE_OPER_TYPE);
                if (Objects.nonNull(nodeOperType)){
                    String operEventType = NodeOperEventTypeEnum.BEFORE.name();
                    JsonNode operEventTypeNode = node.get(OPER_EVENT_TYPE);
                    if (Objects.nonNull(operEventTypeNode)){
                        operEventType = operEventTypeNode.textValue();
                    }

                    String callType = EventCallTypeEnum.SYNC.getType();
                    JsonNode callTypeNode = node.get(CALL_TYPE);
                    if (Objects.nonNull(callTypeNode)){
                        callType = callTypeNode.textValue();
                    }
                    DeployedEventConfigDomain temp = new DeployedEventConfigDomain();

                    temp.setEventType(operEventType+"_"+nodeOperType.textValue());

                    String callUrl = node.get(CALL_URL).textValue();
                    String requestBody = node.get(REQUEST_BODY).textValue();
                    temp.setName(operEventType+"_"+nodeOperType.textValue());
                    temp.setCallMethod(callType);
                    temp.setCallbackParam(Optional.ofNullable(node.get("callbackParam")).map(JsonNode::textValue).orElse(null));
                    temp.setRequestBody(requestBody);
                    temp.setModelId(context.getModelNode().get("modelId").textValue());
                    temp.setModelKey(context.getModelNode().get("properties").get("process_id").textValue());
                    temp.setModelName(context.getModelNode().get("properties").get("name").textValue());
                    temp.setNodeCode(nodeCode);
                    temp.setDeploymentId(context.getDeployId());

                    if (StringUtils.isNotBlank(callUrl)) {
                        temp.setCallbackContent(callUrl);
                        eventConfigRepository.insertEventConfig(temp);
                    }
                }
            }
        }
    }
}
